<?php
class cashierModel extends RPHP_Model
{
    // 处理微信支付成功的异步数据
    public function checkWeixinNotify($da)
    {
        $code = 900;

        if ($da['result_code'] == "SUCCESS" && $da['return_code'] == "SUCCESS" && $da['transaction_id'] != "") {

            $pay_order_id = intval(substr($da['out_trade_no'], 15, strlen($da['out_trade_no']) - 15));
            $total_fee    = intval($da['total_fee']);
            $trade_type   = addslashes(trim($da['trade_type']));
            $pay_time     = strtotime($da['time_end']);

            $pay_order = $this->getPayOrder($pay_order_id);
            if ($pay_order) {
                $channel = $this->getChannel($pay_order['channel_id']);
                if ($channel['appid'] == $da['appid'] && $channel['mchid'] == $da['mch_id'] && $total_fee == $pay_order['total_fee'] && $da['trade_type'] == $channel['trade_type']) {

                    $this->db->begin();
                    $commit = false;
                    $code   = 801;

                    $tmpdata['order_id']       = $pay_order['out_trade_no'];
                    $tmpdata['pay_time']       = $pay_time;
                    $tmpdata['transaction_id'] = $pay_order_id;
                    $tmpdata['total_fee']      = $pay_order['total_fee'];

                    // 执行商品订单
                    if ($pay_order['out_trade_type'] == "ORDER" || $pay_order['out_trade_type'] =="ORDERPAT") {

                        $code = $this->updateOrderInfo($tmpdata);

                    }
                    // 执行开通会员
                    elseif ($pay_order['out_trade_type'] == "MEMBER") {

                        $code = $this->updateMemberInfo($tmpdata);

                    }// 执行九云币充值
                    elseif ($pay_order['out_trade_type'] == "COINS") {

                        $code = $this->updateCoinsInfo($tmpdata);

                    }

                    if ($code == 200) {

                        // 更新支付订单
                        $sql = "UPDATE {$this->_prefix['primary']}pay_order SET `status`=1,`transaction_id`='" . $da['transaction_id'] . "',`transaction_time`=" . $pay_time . ",`notify_status`=2 WHERE `pay_order_id`=" . $pay_order['pay_order_id'];
                        $rcp = $this->sql($sql);
                        if ($rcp > 0) {
                            $code   = 200;
                            $commit = true;
                        } else {
                            $code = 403;
                        }
                    }

                    if ($commit) {
                        $this->db->commit();
                    } else {
                        $this->db->rollback();
                    }

                } else {
                    $code = 800;
                }
            } else {
                $code = 404;
            }
        }
    }

    // 更新商品订单支付
    public function updateOrderInfo($da)
    {
        $code  = 404;
        $sql   = "SELECT * FROM {$this->_prefix['primary']}order_info WHERE `order_id`=" . $da['order_id'];
        $order = $this->db->getrow($sql);
        if ($order) {
            if ($order['order_status'] == 0 && $order['pay_status'] == 0 && $order['pay_total_fee'] == $da['total_fee']) {

                $sql = "UPDATE {$this->_prefix['primary']}order_info SET `order_status`=1,`pay_status`=2,`transaction_id`='" . $da['transaction_id'] . "',`pay_time`=" . $da['pay_time'] . " WHERE `order_id`=" . $order['order_id'];
                $rcs = $this->sql($sql);
                if ($rcs > 0) {
                    //如果是一元拍购买
                    if($order['sell_type']==4){
                        $sql = "UPDATE {$this->_prefix['primary']}order_bidrecord SET `pay_status`=1  WHERE `order_id`=" . $order['order_id'];
                        $ob = $this->sql($sql);
                        
                        $sql     = "SELECT `id` FROM {$this->_prefix['primary']}order_bidrecord WHERE `order_id` = ".$order['order_id'] ." AND `status`=1";
                        $pat_id = $this->db->getone($sql);
                   
                        if($ob){
                            //查出商品保证金
                            $sql   = "SELECT `goods_id` FROM {$this->_prefix['primary']}order_goods WHERE `order_id`=" . $da['order_id'];
                            $goods_id = $this->db->getone($sql);
                            
                            if($goods_id){
                                $sql   = "SELECT `pat_guarantee_price` FROM {$this->_prefix['primary']}goods_pat WHERE `oid`=" . $pat_id;
                                $guarantee_price = $this->db->getone($sql);
                                if($guarantee_price){
                                     
                                    $sql = "UPDATE {$this->_prefix['primary']}finance_balance SET `coins_money`=`coins_money`+" . $guarantee_price . ",`freeze_coins_money`=`freeze_coins_money`-" . $guarantee_price . ",`update_time`=" .$da['pay_time'] . " WHERE `uid`=" . $order['uid'];
                                    $rd  = $this->sql($sql);
                                    if ($rd > 0) {
                                        
                                        //
                                        $balance = $this->db->getrow("SELECT `coins_money`,`freeze_coins_money` FROM {$this->_prefix['primary']}finance_balance WHERE `uid`=" . $order['uid']);
                                        //插入资金明细
                                        $detail_note = '一元拍商品付款成功，九云币解冻' . $guarantee_price . '元';
                                        $sql         = "INSERT INTO {$this->_prefix['primary']}finance_coins (`uid`,`event`,`cmoney`,`money`,`freeze`,`dataid`,`table_name`,`create_time`,`note`) VALUES (" . $order['uid'] . ",5," . $guarantee_price . "," . $balance['coins_money'] . "," . $balance['freeze_coins_money']. "," . $order['order_id'] . ",'order_info'," . $da['pay_time']. ",'" . $detail_note . "')";
                                        $detail_id   = $this->sql($sql);
                                        
                                        if($detail_id){
                                            $code = 200;
                                            
                                        }else{
                                            
                                            $code = 409;
                                        }
                                        
                                    }else{
                                        
                                        $code = 408;
                                    }
                                }else{
                                    $code = 407;
                                }
                            
                            }else{
                                
                                $code = 406;
                            }
                            
                            
                        }else{
                            
                            $code = 405;
                        }
                        
                    }else{
                        $code = 200;
                        
                    }
                   
                } else {
                    $code = 403;
                }

            } else {
                $code = 405;
            }
        }

        return $code;
    }

    // 执行开通会员操作
    public function updateMemberInfo($da)
    {
        $code  = 404;
        $sql   = "SELECT * FROM {$this->_prefix['primary']}member_payinfo WHERE `order_id`=" . $da['order_id'];
        $order = $this->db->getrow($sql);
        if ($order) {

            if ($order['pay_status'] == 0 && $order['pay_time'] == 0 && intval($order['money'] * 100) == $da['total_fee']) {
                $past_time = strtotime("+1 years");

                // 更新开通会员订单表
                $sql = "UPDATE {$this->_prefix['primary']}member_payinfo SET `pay_status`=2,`transaction_id`='" . $da['transaction_id'] . "',`pay_time`=" . $da['pay_time'] . ",`past_time`=" . $past_time . " WHERE `order_id`=" . $order['order_id'];
                $rcs = $this->sql($sql);
                if ($rcs > 0) {

                    // 更新会员级别与到期时间

                    $user = $this->getMemberAccount($order['uid']);
                    if ($user) {

                        $code = 403;

                        $money = intval($order['level_money']);
                        if ($money == 365) {
                            $member_level = 1;
                        } elseif ($money == 1500) {
                            $member_level = 2;
                        } elseif ($money == 6000) {
                            $member_level = 3;
                        }

                        $sql = "UPDATE {$this->_prefix['primary']}member_account SET `member_level`=" . $member_level . ",`level_time`=" . $_SERVER['REQUEST_TIME'] . ",`level_past_time`=" . $past_time . " WHERE `uid`=" . $user['uid'];
                        $rcu = $this->sql($sql);

                        if ($rcu > 0) {

                            $code = 200;
                        }
                    } else {
                        $code = 701;
                    }

                }

            } else {
                $code = 405;
            }
        }

        return $code;
    }
    
    //支付成功增加九云币
    public function updateCoinsInfo($da)
    {
        
      
        $sql   = "SELECT * FROM {$this->_prefix['primary']}coins_recharge WHERE `id`=" . $da['order_id'];
        $coins = $this->db->getrow($sql);
       
        if($coins){
            if ($coins['pay_status'] == 0 && $coins['pay_time'] == 0 && intval($coins['money'] * 100) == $da['total_fee']) {
               
                $code  = 404;
                $sql = "UPDATE {$this->_prefix['primary']}finance_balance SET `coins_money`=`coins_money`+" . $coins['money'] . ",`update_time`=" . $_SERVER['REQUEST_TIME'] . " WHERE `uid`=" . $coins['uid'];
                $rc = $this->sql($sql);
                if($rc){
                    $sql = "UPDATE {$this->_prefix['primary']}coins_recharge SET `pay_status`=1,`transaction_id`='" . $da['transaction_id'] . "',`pay_time`=" . $da['pay_time'] .  " WHERE `id`=" . $da['order_id'];
                    $res = $this->sql($sql);
                    if($res){
                         $balance = $this->db->getrow("SELECT * FROM {$this->_prefix['primary']}finance_balance WHERE `uid`=" .$coins['uid']);
                        //插入资金明细
                        $detail_note = '充值成功，增加九云币' . $coins['money']. '元';
                        $sql         = "INSERT INTO {$this->_prefix['primary']}finance_coins (`uid`,`event`,`cmoney`,`money`,`freeze`,`create_time`,`note`) VALUES (" . $coins['uid'] . ",12," .  $coins['money'] . "," . $balance['coins_money'] . "," . $balance['freeze_coins_money']. "," . $_SERVER['REQUEST_TIME'] . ",'" . $detail_note . "')";
                        $detail_id   = $this->sql($sql);
                        
                        if($detail_id){
                            $code  =200;
                            
                        }else{
                            
                            $code  =409;
                        }
                    }else{
                        $code  =408;
                        
                    }
                        
                        
                    }else{
                        $code = 407;
                        
                    }
                    
                }else{
                    
                    $code = 406;
                }
            }else{
                $code = 405;
                
            }
        
       
        return $code;
    }

    // 获取会员资料
    public function getMemberAccount($uid)
    {
        $sql = "SELECT * FROM {$this->_prefix['primary']}member_account WHERE `uid`=" . intval($uid);
        return $this->db->getrow($sql);
    }

    // 获取支付订单数据
    public function getPayOrder($pay_order_id = 0)
    {
        $sql = "SELECT * FROM {$this->_prefix['primary']}pay_order WHERE `pay_order_id`=" . intval($pay_order_id);
        return $this->db->getrow($sql);
    }

    // 创建支付订单
    public function createPayOrder($da)
    {
        $code = 900;

        $channel_id     = intval($da['channel_id']);
        $out_trade_type = strtoupper(addslashes(htmlspecialchars(trim($da['out_trade_type']))));
        $timestamp      = addslashes(htmlspecialchars(trim($da['timestamp'])));
        $out_trade_no   = addslashes(htmlspecialchars(trim($da['out_trade_no'])));
        $total_fee      = intval($da['total_fee']);

        if ($channel_id > 0 && $this->c['trade']['out_trade_type'][$out_trade_type] && $out_trade_no != "" && $total_fee > 0 && $da['sign'] != "" && $timestamp) {
            $channel = $this->getChannel($channel_id);
           
            if ($channel) {

                // 制作签名
                $para['channel_id']     = $channel['channel_id'];
                $para['out_trade_no']   = $out_trade_no;
                $para['out_trade_type'] = $out_trade_type;
                $para['total_fee']      = $total_fee;
                $para['timestamp']      = $timestamp;
                ksort($para);
                foreach ($para as $key => $value) {
                    $tmp[] = $key . "=" . $value;
                }
                $stringSignTemp = implode("&", $tmp) . "&channer_key=" . $channel['channer_key'];
                $para['sign']   = strtoupper(md5($stringSignTemp));

                // 比对签名
                if ($para['sign'] == $da['sign']) {

                    // 是否需要微信OPENID
                    if ($channel['channel_id'] == 1000) {
                        $getopenid = true;
                    } else {
                        $getopenid = false;
                    }

                    // 查询相应数据是否存在
                    $order = $this->checkData($out_trade_type, $out_trade_no, $total_fee, $getopenid);
                  
                    if ($order['code'] == 200) {

                        $this->db->begin();
                        $commit = false;
                        $code   = 403;

                        // 创建支付订单
                        $sql = "INSERT INTO {$this->_prefix['primary']}pay_order (
                        `channel_id`,
                        `out_trade_type`,
                        `out_trade_no`,
                        `sub_openid`,
                        `total_fee`,
                        `create_time`
                        ) VALUES (
                        " . $channel['channel_id'] . ",
                        '" . $out_trade_type . "',
                        '" . $out_trade_no . "',
                        '" . $order['openid'] . "',
                        '" . $total_fee . "',
                        " . $_SERVER['REQUEST_TIME'] . "
                        )";

                        $pay_order_id = $this->sql($sql);
                        if ($pay_order_id > 0) {
                            // 微信公众号H5支付
                            if ($channel['trade_type'] == "JSAPI") {
                                $data = $this->getWeixinPrepayId($channel, $pay_order_id, $total_fee, $order['openid']);
                                if ($data['code'] == 200) {
                                    $commit = true;
                                    $code   = 200;
                                } else {
                                    $code = $data['code'];
                                }
                            }
                            // 微信APP支付
                            elseif ($channel['trade_type'] == "WXAPP") {
                                $data = $this->makeWXAPPPayInfo($channel, $pay_order_id, $total_fee);
                                if ($data['code'] == 200) {
                                    $commit = true;
                                    $code   = 200;
                                } else {
                                    $code = $data['code'];
                                }
                            }
                        }

                        if ($commit) {
                            $this->db->commit();
                        } else {
                            $this->db->rollback();
                        }

                    } else {

                        $code = 404;
                    }

                } else {
                    $code = 402;
                }

            } else {
                $code = 401;
            }
        }

        return array(
            'code'         => $code,
            'channel'      => $channel,
            'pay_order_id' => $pay_order_id,
            'data'         => $data,
            'order'        => $order,
        );

    }

    // 获取用户OPENID
    public function getUserOpenid($uid)
    {
        if ($uid != "") {
            $sql = "SELECT `openid` FROM {$this->_prefix['primary']}member_wechat WHERE `uid`=" . intval($uid);
            return $this->db->getone($sql);
        }
    }

    // 查询数据是否存在
    public function checkData($out_trade_type, $out_trade_no, $total_fee, $getopenid = true)
    {
        // 商品订单
        if ($out_trade_type == "ORDER" || $out_trade_type == "ORDERPAT") {
            $order_id = intval($out_trade_no);
            $sql      = "SELECT * FROM {$this->_prefix['primary']}order_info WHERE `order_id`=" . $order_id . " AND `order_status`=0 AND `pay_status`=0 LIMIT 1";
            $data     = $this->db->getrow($sql);
            if ($data) {
                $pay_fee = intval($data['pay_total_fee']);
                if ($pay_fee == $total_fee) {
                    $data['code'] = 200;
                    if ($getopenid) {
                        $data['openid'] = $this->getUserOpenid($data['uid']);
                    }

                } else {
                    $data = array(
                        'code'    => 1001,
                        'data'    => $data,
                        'pay_fee' => $pay_fee,
                    );
                }

                return $data;
            }
        }
        // 开通会员
        elseif ($out_trade_type == "MEMBER") {
            //intval($data['money'] * 100);
            $order_id = intval($out_trade_no);
            $sql      = "SELECT * FROM {$this->_prefix['primary']}member_payinfo WHERE `order_id`=" . $order_id . " AND `pay_status`=0 LIMIT 1";
            $data     = $this->db->getrow($sql);
            if ($data) {
                $pay_fee = intval($data['money'] * 100);
                if ($pay_fee == $total_fee) {
                    $data['code'] = 200;
                    if ($getopenid) {
                        $data['openid'] = $this->getUserOpenid($data['uid']);
                    }

                } else {
                    $data = array(
                        'code'    => 1001,
                        'data'    => $data,
                        'pay_fee' => $pay_fee,
                    );
                }

                return $data;
            }
        }
        
        //九云币充值
        elseif ($out_trade_type == "COINS") {
            $order_id = intval($out_trade_no);
            $sql   = "SELECT * FROM {$this->_prefix['primary']}coins_recharge WHERE `id`=" . $order_id;
            $data = $this->db->getrow($sql);
            if ($data) {
                $pay_fee = intval($data['money'] * 100);
                if ($pay_fee == $total_fee) {
                    $data['code'] = 200;
                    if ($getopenid) {
                        $data['openid'] = $this->getUserOpenid($data['uid']);
                    }
        
                } else {
                    $data = array(
                        'code'    => 1001,
                        'data'    => $data,
                        'pay_fee' => $pay_fee,
                    );
                }
        
                return $data;
            }
        }
    }

    // 获取支付渠道数据
    public function getChannel($channel_id)
    {
        $sql = "SELECT * FROM {$this->_prefix['primary']}pay_channel WHERE `channel_id`=" . $channel_id . " AND `status`=1";
        return $this->db->getrow($sql);

    }

    // 生成微信APP支付信息
    public function makeWXAPPPayInfo($channel, $pay_order_id = 0, $total_fee = 0)
    {
        $code = 811;

        if ($channel['appid'] != "" && $channel['mchid'] != "" && $channel['mchkey'] != "" && $pay_order_id > 0 && $total_fee > 0) {
            $code  = 200;
            $money = number_format($total_fee / 100, 2, ".", "");

            $para['ProductName'] = '支付金额';
            $para['Desicript']   = '支付金额' . $money . '元';
            $para['OuttradeNo']  = "JJPAY" . $_SERVER['REQUEST_TIME'] . $pay_order_id;
            $para['Price']       = $money;

        }

        return array(
            'code' => $code,
            'para' => $para,
        );
    }

    //执行微信支付统一下单参数
    public function getWeixinPrepayId($channel, $pay_order_id = 0, $total_fee = 0, $openid = '')
    {

        $code = 811;

        if ($channel['appid'] != "" && $channel['mchid'] != "" && $channel['mchkey'] != "" && $pay_order_id > 0 && $total_fee > 0) {

            if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
                $http_prefix = 'https';
            } else {
                $http_prefix = 'http';
            }

            $para['appid']            = $channel['appid'];
            $para['mch_id']           = $channel['mchid'];
            $para['nonce_str']        = md5($_SERVER['REQUEST_TIME'] . $pay_order_id);
            $para['body']             = '支付金额' . number_format($total_fee / 100, 2, ".", "") . '元';
            $para['time_start']       = date("YmdHis");
            $para['time_expire']      = date("YmdHis", strtotime("+2 days"));
            $para['out_trade_no']     = "LTPAY" . $_SERVER['REQUEST_TIME'] . $pay_order_id;
            $para['total_fee']        = $total_fee;
            $para['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'];
            $para['notify_url']       = $http_prefix . "://" . $_SERVER['HTTP_HOST'] . "/cashier/wxnotify";
            $para['trade_type']       = $channel['trade_type'];
            if ($openid != "") {
                $para['openid'] = $openid;
            }

            ksort($para);
            foreach ($para as $key => $value) {
                $tmp[] = $key . "=" . $value;
                $xml .= "<" . $key . ">" . $value . "</" . $key . ">";
            }

            $stringSignTemp = implode("&", $tmp) . "&key=" . $channel['mchkey'];

            $para['sign'] = strtoupper(md5($stringSignTemp));
            $xml .= "<sign>" . $para['sign'] . "</sign>";
            //print_r($para);
            //生成XML
            $xml = '<xml>
                    ' . $xml . '
                    </xml>';
            $url     = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
            $xmldata = $this->postXmlCurl($xml, $url);

            if ($xmldata != "") {
                libxml_disable_entity_loader(true);
                $xdata = json_decode(json_encode(simplexml_load_string($xmldata, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

                if ($xdata['return_code'] == "SUCCESS" && $xdata['prepay_id'] != "") {

                    $prepay_id = $xdata['prepay_id'];

                    //更新订单的->prepay_id
                    $sql  = "UPDATE {$this->_prefix['primary']}pay_order SET `prepay_id`='" . $prepay_id . "' WHERE `pay_order_id`=" . $pay_order_id;
                    $rcup = $this->sql($sql);
                    if ($rcup > 0) {
                        $code = 200;
                    } else {

                        $code = 816;
                    }

                } else {
                    $code = 817;
                }

            } else {
                $code = 812;
            }

        }
        return array(
            'code'       => $code,
            'error_code' => $xdata['return_code'],
            'prepay_id'  => $prepay_id,
        );

    }

    //获取微信JSPAY参数
    public function getJSAPIPara($channel, $prepay_id, $pay_order_id)
    {
        $para['appId']     = $channel['appid'];
        $para['timeStamp'] = $_SERVER['REQUEST_TIME'];
        $para['nonceStr']  = md5($prepay_id . $_SERVER['REQUEST_TIME']);
        $para['package']   = 'prepay_id=' . $prepay_id;
        $para['signType']  = "MD5";

        ksort($para);

        foreach ($para as $key => $value) {
            $tmp[] = $key . "=" . $value;
        }

        $stringSignTemp       = implode("&", $tmp) . "&key=" . $channel['mchkey'];
        $para['paySign']      = strtoupper(md5($stringSignTemp));
        $para['pay_order_id'] = $pay_order_id;

        return $para;

    }

    //POST XML
    public function postXmlCurl($xml, $url, $second = 30)
    {
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //严格校验
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, false);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        //post提交方式
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            echo ("curl出错，错误码:$error");
        }
    }

}
